package top.jle.locker.aspect;


import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.aspect.Invocation;
import org.noear.solon.core.util.SupplierEx;
import org.noear.solon.core.util.TmplUtil;
import top.jle.locker.annotation.OperationLock;
import top.jle.locker.config.LockerConfig;
import top.jle.locker.integration.Locker;

import java.util.concurrent.atomic.AtomicReference;

/**
 * 分布式锁切面
 * @author  jim.lee
 * 2022/5/11 10:08
 */
@Component
public class OperationLockExecutorImpl {
    @Inject
    private Locker locker;
    @Inject
    private LockerConfig lockerConfig;

    public <T> Object lock(OperationLock anno, Invocation inv, SupplierEx<T> executor) throws Throwable {
        if(anno==null){
            return executor.get();
        }
        //获取锁前缀
        String lockKeyPrefix = anno.lockKeyPrefix();
        String lockKey = TmplUtil.parse(anno.expression(), inv);
        AtomicReference<Object> obj = new AtomicReference<>();
        long releaseTime = anno.releaseTime();
        locker.lock(lockKeyPrefix,lockKey,releaseTime,()-> obj.set(executor.get()));
        return obj.get();
    }
}
